/*
 * Cell.h
 *
 *  Created on: Feb 28, 2011
 *      Author: wjfortin
 */
#ifndef CELL_H_
#define CELL_H_

#include <vector>
#include "data/Molecule.h"
#include "data/Protein.h"
#include "data/DNA.h"
#include "data/MRNA.h"
#include "data/Interaction.h"
#include "MersenneTwister.h"
#include "Constants.h"
#include <lemon/list_graph.h>
#include "Trace.h"
#include <fstream>
#include <sys/stat.h>
#include <sys/types.h>


#include <typeinfo>

using namespace lemon;
using namespace std;

class Cell {
public:
	Cell();
	virtual ~Cell();
	int nextGeneration();
	int getScore(int);
	int getCellID();
	ListDigraph* equations;
	ListDigraph::NodeMap<Molecule*>* vertexes;
	ListDigraph::ArcMap<Interaction*>* edges;

	//TODO 6/4/11 comment and document in the report.
	vector<Protein*> proteinList;

	ListDigraph::Node addProtein(float);
	ListDigraph::Node addProtein(Protein*);
	ListDigraph::Node addMRNA(float);
	ListDigraph::Node addDNA(float);

	ListDigraph::Arc addInteraction(ListDigraph::Node, ListDigraph::Node, float, float, float, const char*);
	ListDigraph::Arc addInteraction(ListDigraph::Node, ListDigraph::Node, Quantity*, float, float, const char*);

	int newComplex();
	int newBasic();
	int fwdRateChange();
	int revRateChange();
	int degRateChange();
	int newPostTransMod();

	int histoneMod();
	int newPromoter();

	bool isComplexed(Protein*, Protein *);

	int cellID;

	void rungeKuttaEvaluate(float, float);

private:

	ListDigraph::Node getRandomProtein();
	ListDigraph::Node * degraded;
	int mutate();
	vector<Quantity*> constants;
	int numGenerations;
	static int cellCounter;
	MTRand r;
	ListDigraph::Node nullNode;

	int moleculeCount;
	int numProtein;
	int numMRNA;
	int numDNA;

	ofstream mutationLog;

	float rkDataLimit;
	float rkDataStep;

	void cleanRkData(float, float);
	void outputRungeKuttaData();

};

#endif /* CELL_H_ */
